/*************************************************
 * File:    		SMJS_Document.h
 * Author:  	HouJiong <hou_jiong@163.com>
 * Brief:   		StoneMoneky project.
 *
 * Copyright (c) HouJiong
 *
 *************************************************/

/*
 * History:
 * =======================================
 * 2009-04-10 HouJiong <hou_jiong@163.com> created
 */
 
#include "SMJS_Document.h"

#define JSDOCUMENT_SETElEMENTVALUE 3
#define JSDOCUMENT_GETElEMENTVALUE 2
#define JSDOCUMENT_ANIMATE 4
#define JSDOCUMENT_PRINT 2
std::string Document::GetElementValue(std::string element,std::string attribute)
{
	ElementList::iterator nodeIterator;  
   
	for(nodeIterator = m_SMXMLDOM->getElementList().begin(); nodeIterator !=  m_SMXMLDOM->getElementList().end(); nodeIterator++)   
	{  
		if(element==(*nodeIterator).getAttribute("id"))
		{
			return (*nodeIterator).getAttribute(attribute);
		}
	}
}

void Document::SetElementValue(std::string element,std::string attribute,std::string value)
{
	ElementList::iterator nodeIterator;  
   
	for(nodeIterator = m_SMXMLDOM->getElementList().begin(); nodeIterator !=  m_SMXMLDOM->getElementList().end(); nodeIterator++)   
	{  
		if(element==(*nodeIterator).getAttribute("id"))
		{	
			(*nodeIterator).setAttribute(attribute,value);
		}
	}

	SMFactory::instance()->getview()->update();
}


JSPropertySpec JSDocument::Document_properties[] = 
{     
//	{ "name", name_prop, JSPROP_ENUMERATE },   
//	{ "age", age_prop, JSPROP_ENUMERATE },	
	{ 0 }
};

JSFunctionSpec JSDocument::Document_methods[] =
{  
	//{ "computeReduction", computeReduction, 1, 0, 0 },	
	{ "GetElementValue", GetElementValue, JSDOCUMENT_GETElEMENTVALUE, 0, 0 },	
	{ "SetElementValue", SetElementValue, JSDOCUMENT_SETElEMENTVALUE, 0, 0 },	
	{ "Print", Print, JSDOCUMENT_PRINT, 0, 0 },	
	{ 0, 0, 0, 0, 0 }
};

JSClass JSDocument::Document_class = 
{ 
		"Document", 
		JSCLASS_HAS_PRIVATE, JS_PropertyStub, JS_PropertyStub,	
		0, 0,
		JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,
		JSDocument::JSDestructor
};

/*
JSBool JSDocument::JSGetProperty(JSContext *cx, JSObject *obj, jsval id,jsval *vp)
{  
	if (JSVAL_IS_INT(id)) 	
	{		
		JSDocument *p = (JSDocument *) JS_GetPrivate(cx, obj);		
		Document *customer = p->getCustomer();  
		switch (JSVAL_TO_INT(id)) 	
		{	
			case name_prop:		
				{			
					std::string name = customer->GetName();	
					JSString *str = JS_NewStringCopyN(cx, name.c_str(), name.length());		
					*vp = STRING_TO_JSVAL(str);				
					break;			
				}		
				case age_prop:	
					*vp = INT_TO_JSVAL(customer->GetAge());		
					break;      
			}    
	}   
	
	return JS_TRUE;
}

JSBool JSDocument::JSSetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{    
	if (JSVAL_IS_INT(id)) 
	{	
		JSCustomer *p = (JSCustomer *) JS_GetPrivate(cx, obj);		
		Document *customer = p->getCustomer();    
		switch (JSVAL_TO_INT(id)) 	
		{	
			case name_prop:		
				{		
					JSString *str = JS_ValueToString(cx, *vp);		
					std::string name = JS_GetStringBytes(str);				
					customer->SetName(name);		
					break;		
				}	
			case age_prop:	
					customer->SetAge(JSVAL_TO_INT(*vp));	
					break;		
			}   
		}   
	
	return JS_TRUE;
}

*/
JSBool JSDocument::JSConstructor(JSContext *cx, JSObject *obj, uintN argc,	jsval *argv, jsval *rval)
{	
	JSDocument *priv = new JSDocument();
	priv->setDocument(new Document(SMFactory::instance()->getSMXMLDOM()));	
	JS_SetPrivate(cx, obj, (void *) priv);	
	return JS_TRUE;
}

void JSDocument::JSDestructor(JSContext *cx, JSObject *obj)
{	
	JSDocument *priv = (JSDocument*) JS_GetPrivate(cx, obj);	
	delete priv;	
	priv = NULL;
}

JSObject *JSDocument::JSInit(JSContext *cx, JSObject *obj, JSObject *proto)
{   
	JSObject *newProtoObj =JS_InitClass(cx, obj, proto, &Document_class, JSDocument::JSConstructor, 0, NULL, JSDocument::Document_methods,	NULL, NULL);	
	//JS_DefineProperties(cx, newProtoObj, JSCustomer::Customer_properties); 
	return newProtoObj;
}

/*
JSBool JSDocument::computeReduction(JSContext *cx, JSObject *obj, uintN argc,	jsval *argv, jsval *rval)
{   
	JSDocument *p = (JSDocument*) JS_GetPrivate(cx, obj);	
	*rval =INT_TO_JSVAL(p->getCustomer()->GetAge());  
	 if ( p->getCustomer()->GetAge() < 25 )    
			*rval = INT_TO_JSVAL(10);   
	else     
			*rval = INT_TO_JSVAL(5);    
	return JS_TRUE;
}
*/

JSBool JSDocument::GetElementValue(JSContext *cx, JSObject *obj, uintN argc,	jsval *argv, jsval *rval)
{   

	if(argc!=JSDOCUMENT_GETElEMENTVALUE)
	{
		return JS_TRUE;
	}

	JSString *str;		
	std::string element; 	
	std::string attribute; 
	

	str= JS_ValueToString(cx, *(argv));
	element= JS_GetStringBytes(str);
	
	str= JS_ValueToString(cx, *(++argv));
	attribute= JS_GetStringBytes(str);	

	JSDocument *p = (JSDocument *) JS_GetPrivate(cx, obj);		
	Document *d= p->getDocument();   	

	str = JS_NewStringCopyN(cx, (d->GetElementValue(element, attribute)).c_str(), (d->GetElementValue(element, attribute)).length());		
	*rval = STRING_TO_JSVAL(str);	

	return JS_TRUE;
	
}

JSBool JSDocument::SetElementValue(JSContext *cx, JSObject *obj, uintN argc,	jsval *argv, jsval *rval)
{   

	if(argc!=JSDOCUMENT_SETElEMENTVALUE)
	{
		return JS_TRUE;
	}

	JSString *str;		
	std::string element; 	
	std::string attribute; 
	std::string value; 
	

	str= JS_ValueToString(cx, *(argv));
	element= JS_GetStringBytes(str);
	
	str= JS_ValueToString(cx, *(++argv));
	attribute= JS_GetStringBytes(str);	

	str= JS_ValueToString(cx, *(++argv));
	value= JS_GetStringBytes(str);
	
	JSDocument *p = (JSDocument *) JS_GetPrivate(cx, obj);		
	Document *d= p->getDocument();   	

	d->SetElementValue(element, attribute,value);
	//str = JS_NewStringCopyN(cx, (d->GetElementValue(element, attribute)).c_str(), (d->GetElementValue(element, attribute)).length());		
	//*rval = STRING_TO_JSVAL(str);	
	
	return JS_TRUE;
}

JSBool JSDocument::Print(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{

	std::cout<<"Document Print"<<std::endl;
	return JS_TRUE;
}